package com.zzyl.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.gson.JsonObject;
import com.zzyl.base.PageBean;
import com.zzyl.constant.Constants;
import com.zzyl.constant.WeChatConstants;
import com.zzyl.dto.UserLoginRequestDto;
import com.zzyl.entity.Member;
import com.zzyl.mapper.MemberMapper;
import com.zzyl.properties.JwtTokenProperties;
import com.zzyl.properties.WeChatProperties;
import com.zzyl.service.ContractService;
import com.zzyl.service.MemberElderService;
import com.zzyl.service.MemberService;
import com.zzyl.service.OrderService;
import com.zzyl.utils.JwtUtil;
import com.zzyl.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MemberServiceImpl implements MemberService {

    private static final List<String> DEFAULT_NICKNAME_PREFIX =
            List.of("生活更美好", "大桔大利", "日富一日", "好柿开花", "柿柿如意", "一椰暴富", "大柚所为", "杨梅吐气", "天生荔枝");

    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private ContractService contractService;
    @Autowired
    private MemberElderService memberElderService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private JwtTokenProperties jwtTokenProperties;
    @Autowired
    private WeChatProperties weChatProperties;
    /**
     * 根据id查询用户
     *
     * @param id 用户id
     * @return 用户信息
     */
    @Override
    public Member getById(Long id) {
        return memberMapper.selectById(id);
    }

    /**
     * 分页查询用户列表
     *
     * @param page     当前页码
     * @param pageSize 每页数量
     * @param phone    手机号
     * @param nickname 昵称
     * @return 分页结果
     */
    @Override
    public PageBean<MemberVo> page(Integer page, Integer pageSize, String phone, String nickname) {
        PageHelper.startPage(page, pageSize);
        Page<Member> listPage = memberMapper.page(phone, nickname);

        PageBean<MemberVo> pageBean = PageBean.of(listPage, MemberVo.class);

        pageBean.getRecords().forEach(memberVo -> {
            List<ContractVo> contractVos = contractService.listByMemberPhone(memberVo.getPhone());
            memberVo.setIsSign(contractVos.isEmpty() ? "否" : "是");
            List<OrderVo> orderVos = orderService.listByMemberId(memberVo.getId());
            memberVo.setOrderCount(orderVos.size());
            List<MemberElderVo> memberElderVos = memberElderService.listByMemberId(memberVo.getId());
            List<String> collect = memberElderVos.stream().map(m -> m.getElderVo().getName()).collect(Collectors.toList());
            memberVo.setElderNames(String.join(",", collect));
        });
        return pageBean;
    }

    @Override
    public LoginVo login(UserLoginRequestDto userLoginRequestDto) {;
        //1.调用微信api,根据code获取openId
        //封装参数
        Map<String, Object> requestUrlParam = new HashMap<>();
        requestUrlParam.put("appid", weChatProperties.getAppid());
        requestUrlParam.put("secret", weChatProperties.getSecret());
        requestUrlParam.put("js_code", userLoginRequestDto.getCode());

        String result = HttpUtil.get(WeChatConstants.WX_LOGIN_URL, requestUrlParam);
        JSONObject jsonObject = JSONUtil.parseObj(result);
        String phone;
        // 若code不正确，则获取不到openid，响应失败
        if (ObjectUtil.isNotEmpty(jsonObject.getInt("errcode"))) {
            throw new RuntimeException(jsonObject.getStr("errmsg"));
        }

        String openId = jsonObject.getStr("openid");

        //2.根据openId查询用户
        Member member = memberMapper.getByOpenId(openId);

        //3.如果用户为空，则新增用户
        if (ObjectUtil.isEmpty(member)) {
            //存在openid且未注册那么我们就去尝试获取access_token,通过它获取手机号
            try {
                //用自己小程序的appid和secret获取access_token
                String resultToken = HttpUtil.get(WeChatConstants.WX_TOKEN_URL+
                        "&appid="+weChatProperties.getAppid()+"&secret="+weChatProperties.getSecret());
                JSONObject jsonObjectToken = JSONUtil.parseObj(resultToken);
                String access_token = jsonObjectToken.getStr("access_token");

                JSONObject param = JSONUtil.createObj();
                param.set("code", userLoginRequestDto.getPhoneCode());

                String resultPhone = HttpUtil.post(WeChatConstants.WX_PHONE_URL+access_token,param.toString());

                JSONObject jsonObjectPhone = JSONUtil.parseObj(resultPhone);
                JSONObject  phoneInfo = jsonObjectPhone.getJSONObject("phone_info");
                phone = phoneInfo.getStr("phoneNumber");
            }catch (Exception e){
                throw new RuntimeException("获取手机号失败");
            }

            member = Member.builder().openId(openId).build();
            //随机组装昵称，词组+openid前四位
            String nickName = RandomUtil.randomEle(DEFAULT_NICKNAME_PREFIX) + StringUtils.substring(openId, 0, 4);
            member.setName(nickName);//设置昵称
            if(StringUtils.isNotEmpty(phone))
                member.setPhone(phone);
            memberMapper.save(member);
        }

        //4.将用户id存入token,返回
        Map<String, Object> claims = new HashMap<>();
        claims.put(Constants.JWT_USERID, member.getId());
        claims.put(Constants.JWT_USERNAME, member.getName());

        String token = JwtUtil.createJWT(jwtTokenProperties.getSecretKey(), jwtTokenProperties.getTtl(), claims);

        LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);
        loginVo.setNickName(member.getName());
        return loginVo;
    }
}
